﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using vITs.Site.Models.ActionModels;
using vITs.Site.Models.DataModels;
using vITs.Site.Models;

namespace vITs.Site.Controllers
{
    public class AssignmentController : Controller
    {
        [Authorize(Roles = "Konsult")]
        [HttpGet]
        public ActionResult CreateAssignment()
        {
            List<User> ListofManagers = new List<User>();
            List<SelectListItem> ListofAccounts = new List<SelectListItem>();
            VitsDB db = new VitsDB();
             

            var role = db.Roles.SingleOrDefault(r => r.Name == "Chef");
            if (role == null) return this.Redirect("Error 500"); 
            ViewBag.ListofManagers = role.Users.ToArray();

            var account = db.Accounts.ToList();
            foreach (Account a in account)
            {
                ListofAccounts.Add(new SelectListItem() { Text = a.Name, Value = a.AccountId.ToString()});
            }
            ViewBag.ListofAccounts = ListofAccounts;

            ViewBag.ListofVehicles = new List<SelectListItem> {new SelectListItem() { Text = "Bil", Value ="1" }, new SelectListItem() { Text = "Flygplan", Value = "2" } };

            return View();
        }

        [HttpGet]
        [Authorize(Roles="Konsult")]
        public ActionResult SubmitAssignment(Int32 AssignmentId)
        {
            VitsDB db = new VitsDB();
            var assignment = db.Assignments.SingleOrDefault(a => a.AssignmentId == AssignmentId);
            if (assignment != null && assignment.Consultant.EmailAddress == this.User.Identity.Name)
            {
                if (assignment.IsEditable())
                {
                    assignment.SetStatus(AssignmentStatus.Submitted);
                    db.SaveChanges();
                }
            }

            return this.RedirectToAction("ViewAssignment", "Consultant", new { AssignmentId = AssignmentId });
        }

        [Authorize(Roles = "Konsult")]
        [HttpPost]
        public ActionResult CreateAssignment(CreateAssignmentModel CAM)
        {
            ViewBag.CreatedAssignment = "";

            if(this.ModelState.IsValid)
            {
                VitsDB db = new VitsDB();
                var user = db.Users.SingleOrDefault(u => u.EmailAddress == this.User.Identity.Name);
                var handler = db.Users.SingleOrDefault(u => u.UserId == CAM.Handler);
                Assignment a = new Assignment() { AssignmentName = CAM.Name, Consultant = user, EndDate = CAM.EndDate, StartDate = CAM.StartDate, Handler = handler};

                db.AddToAssignments(a);
                if (db.SaveChanges() == 1)
                {
                    String error;
                    if (!Utilities.TrySendMail(handler, "Nytt Uppdrag", "<h1>Nytt Uppdrag</h1><p>Det finns ett nytt uppdrag att godkänna. <a href=\"" + String.Concat(Utilities.BaseSiteUrl, "Handler/ViewAssignment?AssignmentId=", a.AssignmentId) + "\">Gå till uppdraget</a>.", out error))
                    {
                        this.ModelState.AddModelError("", "Misslyckades med att skicka ett meddelande till chefen. Meddela hen personligen.");
                    }
                    
                    ViewBag.CreatedAssignment = "Du har lyckats att skapa ett uppdrag.";
                }
            }
                
            CreateAssignment();
            
            return this.View(CAM);
        }

        [Authorize(Roles="Konsult")]
        [HttpGet]
        public ActionResult AddExpense(Int32 AssignmentId)
        {
            VitsDB db = new VitsDB();
            var assignment = (from Assignment a in db.Assignments where a.AssignmentId == AssignmentId select a).SingleOrDefault();
            if (assignment == null) return this.RedirectToAction("Index", "Dashboard");

            this.ViewBag.Assignment = assignment;

            return this.View();
        }

        [Authorize(Roles="Konsult")]
        [HttpPost]
        public ActionResult AddExpense(AddExpenseModel model)
        {
            VitsDB db = new VitsDB();
            var assignment = (from Assignment a in db.Assignments where a.AssignmentId == model.AssignmentId select a).SingleOrDefault();

            if (assignment != null)
            {
                this.ViewBag.Assignment = assignment;

                if (this.ModelState.IsValid)
                {
                    if (assignment.Consultant.EmailAddress == this.User.Identity.Name)
                    {
                        Expense expense = new Expense()
                        {
                            Name = model.Name,
                            Date = model.Date,
                            Tax = model.Tax,
                            Sum = model.Sum,
                            Currency = model.Currency,
                            ExchangeRate = model.ExchangeRate,
                            AssignmentId = model.AssignmentId
                        };
                        db.AddToExpenses(expense);

                        if (db.SaveChanges() > 0)
                        {
                            return this.RedirectToAction("AddExpense", new { AssignmentId = model.AssignmentId });
                        }
                        else
                        {
                            this.ModelState.AddModelError("", "Uppgifterna kunde inte sparas.");
                        }
                    }
                    else
                    {
                        this.ModelState.AddModelError("", "Den inloggade användaren är inte uppdragets konsult.");
                    }
                }
            }
            else
            {
                return this.RedirectToAction("Index", "Dashboard");
            }

            return this.View(model);
        }

        [HttpGet]
        [Authorize(Roles = "Konsult")]
        public ActionResult AddTrip(int AssignmentId)
        {
            var assignment = (from Assignment a in new VitsDB().Assignments where a.AssignmentId == AssignmentId select a).SingleOrDefault();
            if (assignment.Consultant.EmailAddress != this.User.Identity.Name)
            {
                return this.RedirectToAction("Index", "Dashboard");
            }

            this.ViewBag.Assignment = assignment;

            return this.View();
        }

        [HttpPost]
        [Authorize(Roles = "Konsult")]
        public ActionResult AddTrip(AddTripModel model)
        {
            VitsDB db = new VitsDB();
            var assignment = (from Assignment a in db.Assignments where a.AssignmentId == model.AssignmentId select a).SingleOrDefault();
            if (assignment.Consultant.EmailAddress != this.User.Identity.Name)
            {
                return this.RedirectToAction("Index", "Dashboard");
            }
            this.ViewBag.Assignment = assignment;

            if (this.ModelState.IsValid)
            {
                Int32 percentUnits = 100; 
                
                /*
                 * Konton fungerar inte än, fixa senare.
                 * 
                foreach (var item in model.Accounts)
                {
                    percentUnits += item.Percentage;
                }
                */

                if (percentUnits == 100)
                {
                    Trip trip = new Trip()
                    {
                        AssignmentId = assignment.AssignmentId,
                        StartLocation = model.StartLocation,
                        StartDate = model.StartDate,
                        EndLocation = model.EndLocation,
                        EndDate = model.EndDate,
                        TransportationCost = model.TransportationCost
                    };
                    trip.SetTransportationMode(model.TransportationMode);

                    db.AddToTrips(trip);
                    if (db.SaveChanges() > 0)
                    {
                        return this.RedirectToAction("ViewAssignment", "Consultant", new { AssignmentId = assignment.AssignmentId });
                    }
                    else
                    {
                        this.ModelState.AddModelError("", "Kunde inte spara resan till databasen.");
                    }
                }
                else
                {
                    this.ModelState.AddModelError("Accounts", "Du måste ange sammanlagt 100 procentenheter.");
                }
            }            

            return this.View(model);
        }

        [HttpGet]
        [Authorize(Roles = "Konsult")]
        public ActionResult AddPerDiem(Int32 AssignmentId)
        {
            VitsDB db = new VitsDB();
            
            var assignment = db.Assignments.SingleOrDefault(a => a.AssignmentId == AssignmentId);
            if (assignment == null) return this.RedirectToAction("Index", "Dashboard");

            this.ViewBag.Assignment = assignment;

            return this.View();
        }

        [HttpPost]
        [Authorize(Roles = "Konsult")]
        public ActionResult AddPerDiem(AddPerDiemModel model)
        {
            VitsDB db = new VitsDB();
            var assignment = (from Assignment a in db.Assignments where a.AssignmentId == model.AssignmentId select a).SingleOrDefault();
            if (assignment == null) return this.RedirectToAction("Index", "Dashboard");

            this.ViewBag.Assignment = assignment;

            if (this.ModelState.IsValid)
            {
                if (DateTime.Compare(model.Date, assignment.StartDate) >= 0 && 0 >= DateTime.Compare(model.Date, assignment.EndDate))
                {
                    if (assignment.PerDiems.SingleOrDefault(p => p.Date == model.Date) == null)
                    {
                        bool onBreak = false;
                        foreach (Break b in assignment.Breaks)
                        {
                            if (DateTime.Compare(model.Date, b.StartDate) >= 0 && 0 >= DateTime.Compare(model.Date, b.EndDate))
                            {
                                onBreak = true;
                            }
                        }

                        if (!onBreak)
                        { 
                            PerDiem pd = new PerDiem()
                            {
                                AssignmentId = model.AssignmentId,
                                Date = model.Date,
                                Country = model.Country.ToUpper(),
                                Breakfast = model.Breakfast,
                                Lunch = model.Lunch,
                                Dinner = model.Dinner
                            };

                            db.AddToPerDiems(pd);
                            Int32 rows = db.SaveChanges();
                            if (rows > 0)
                            {
                                return this.RedirectToAction("AddPerDiem", new { AssignmentId = model.AssignmentId });
                            }
                            else
                            {
                                this.ModelState.AddModelError("", "Traktamentet kunde inte sparas.");
                            }
                        }
                        else
                        {
                            this.ModelState.AddModelError("Date", "Du kan inte rapportera in traktamente för en dag då du rapporterat uppehåll.");
                        }
                    }
                    else
                    {
                        this.ModelState.AddModelError("Date", "Du har redan rapporterat traktamente för den dagen.");
                    }
                }
                else
                {
                    this.ModelState.AddModelError("Date", "Datumet måste ligga inom uppdragets start- och slutdatum.");
                }
            }

            return this.View(model);
        }

        
        public PartialViewResult ViewAssignment(int AssignmentId)
        {
            var assignment =  (from Assignment a in new VitsDB().Assignments where a.AssignmentId == AssignmentId select a).SingleOrDefault();
            if (assignment == null) return null;

            this.ViewBag.Assignment = assignment;

            return this.PartialView();
        }

         //Status, 1 = Skall godkännas 2 = Godkänt uppdrag, 3 = Förskott skall godkännas 4 = Godkänt förskott, 5 = Skall slutgiltigt-godkännas, 6 = slutgiltigt godkänt
        public ActionResult VerifyAssignment(int AssignmentId, int Status)
        {
            VitsDB db = new VitsDB();
            var assignment = db.Assignments.SingleOrDefault(a => a.AssignmentId == AssignmentId);
            assignment.Status = (byte)Status;

            db.SaveChanges();

            return RedirectToAction("ViewAssignment", "Handler", new { AssignmentId = AssignmentId });
        }

        [HttpGet]
        public ActionResult RequestAdvance(Int32 AssignmentId, Double? advance)
        {
            VitsDB db = new VitsDB();
            var assignment = db.Assignments.SingleOrDefault(a => a.AssignmentId == AssignmentId);
            if (assignment == null || assignment.Consultant.EmailAddress != this.User.Identity.Name) this.Json(new { url = this.Url.Action("Index", "Dashboard") }, JsonRequestBehavior.AllowGet);

            string error = String.Empty, url = this.Url.Action("ViewAssignment", "Consultant", new { AssignmentId = AssignmentId });
            if (assignment.GetStatus() == AssignmentStatus.AssignmentApproved)
            {
                if (advance.HasValue)
                {
                    if (advance.Value >= double.Epsilon && advance.Value <= double.MaxValue)
                    {
                        assignment.Advance = advance.Value;
                        assignment.SetStatus(AssignmentStatus.AdvanceRequested);

                        if (db.SaveChanges() > 0)
                        {
                            return this.Json(new { msg = "Du har ansökt om förskott!", url = url }, JsonRequestBehavior.AllowGet);
                        }
                        else
                        {
                            error = "Förskottet kunde inte sparas till databasen.";
                        }
                    }
                    else
                    {
                        error = "Förskottet måste vara ett positivt tal.";
                    }
                }
                else
                {
                    error = "Ett fel uppstod. Kom ihåg att ange decimaltal med punkt som skiljetecken.";
                }
            }
            else
            {
                error = "Du kan inte ansöka om förskott just nu.";
            }

            return this.Json(new { error = error, url = url }, JsonRequestBehavior.AllowGet);
        }
    }
}
